import { forEachValue } from "../utils";
import Module from "./module";

// 模块收集，对模块数据进行格式化处理
class ModuleCollection {
  constructor(options) {
    // 根模块
    this.root = null;
    // 初始化根模块
    this.register([], options);
  }

  // 设置了命名空间，需要对模块添加 /，aa 模块 => a/aa
  getNamespaced(path) {
    // 根模块
    let module = this.root;

    return path.reduce((pre, key) => {
      // 根据属性名获取到当前模块的子模块 【根，a，aa，】
      module = module.getChild(key);

      return pre + (module.namespaced ? `${key}/` : '')
    }, '')
  }

  // 递归格式化处理模块数据
  register(path, rootModule) {
    // 格式化模块数据
    const newModule = new Module(rootModule);
    // 如果动态添加模块，将包装后的module 在原模块上存一份
    rootModule.newModule = newModule;

    if (this.root === null) {
      // 存储一份根模块
      this.root = newModule;
    } else {
      // 处理子模块 => 【根模块】、【根模块，a模块】、【根模块，a模块，aa模块】
      // path => [a]、[a, a/aa]，a模块去获取根模块，aa模块去获取a模块
      // 拿到子模块的对应的父模块
      const parent = path.slice(0, -1).reduce((start, current) => {
        // return start._children[current]
        return start.getChild(current)
      }, this.root);

      // 为每个模块的父模块添加处理好的对应子模块数据
      parent.addChild(path.at(-1), newModule);
      // parent._children[path.at(-1)] = newModule
    }

    // 如果有modules，递归处理子模块
    if (rootModule.modules) {
      forEachValue(rootModule.modules, (moduleName, moduleValue) => {
        this.register(path.concat(moduleName), moduleValue);
      })
    }
  }
}

export default ModuleCollection
